package com.michaelbulava.TFS.jni;

import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.michaelbulava.TFS.TFSVcsApplicationComponent;
import com.michaelbulava.TFS.log.FileLogger;
import com.michaelbulava.TFS.persistence.IdeaPersistenceStoreProvider;
import com.microsoft.tfs.jni.loader.NativeLoader;
import com.microsoft.tfs.util.Check;
import com.microsoft.tfs.util.StringHelpers;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;

/**
 * Created by mbulava on 5/6/2015.
 * This class is utilized by application at startup and shutdown to ensure the JVM gets the
 * TFS Natives into the classpath of the plugin.
 */
public class NativesHelper {
    private static final Logger log = FileLogger.getInstance(NativeLoader.class);
    private static final String OS_FOLDER="lib/os";

    public static boolean setNativeLocation(File nativeLocation){
        Check.notNull(nativeLocation, "nativeLocations");
        String path;
        Check.isTrue(nativeLocation.exists(),
                MessageFormat.format("supplied location [{0}] does not exist.",
                        new Object[]{nativeLocation}));
        Check.isTrue(nativeLocation.isDirectory(),
                MessageFormat.format("supplied location [{0}] is not a directory.",
                        new Object[] { nativeLocation }));
        try{
            path = nativeLocation.getCanonicalPath();
        } catch (IOException e) {
            throw new IllegalArgumentException("cannot get canonical path of nativeLocation");
        }
        System.setProperty(NativeLoader.NATIVE_LIBRARY_BASE_DIRECTORY_PROPERTY,
                path);
        //test the setting
        try{
            IdeaPersistenceStoreProvider.INSTANCE.getCachePersistenceStore();
        } catch(Throwable t){
            log.error(t);
            log.error("Failed to set NativeLocation with a valid value.");
            clearNativeLocation();
            return false;
        }
        log.info("Native Location set to " + path);
        return true;
    }

    public static void clearNativeLocation(){
        System.clearProperty(NativeLoader.NATIVE_LIBRARY_BASE_DIRECTORY_PROPERTY);
        log.info("Cleared natives location");
    }

    public static String getNativeLocation(){
        return System.getProperty(NativeLoader.NATIVE_LIBRARY_BASE_DIRECTORY_PROPERTY);
    }

    public static boolean isNativeSet(){
        return !StringHelpers.isNullOrEmpty(getNativeLocation());
    }

    public static boolean tryToSetNatives(){
        PluginId pluginId = PluginId.getId(TFSVcsApplicationComponent.PLUGIN_ID);
        IdeaPluginDescriptor myPlugin = PluginManager.getPlugin(pluginId);
//        IdeaPluginDescriptor myPlugin = null;
//        if (myPlugin == null){
//            log.warn("Unable to locate plugin using my Id so I've gotta do th");
//            IdeaPluginDescriptor[] plugins = PluginManager.loadDescriptors(null);
//            for (IdeaPluginDescriptor pluginDescriptor : plugins) {
//                if (pluginDescriptor.getPluginId().getIdString().equals(TFSVcsApplicationComponent.PLUGIN_ID)){
//                    myPlugin = pluginDescriptor;
//                    break;
//                }
//            }
//        }
        if (myPlugin != null){
            //String myLocalPath = myPlugin.getPath().getAbsolutePath();

            File osFolder = new File(myPlugin.getPath(), OS_FOLDER);

            if (osFolder.exists()){
                log.info("found default natives location.");
                return setNativeLocation(osFolder);
            }
        }
        //Make sure we clear the property if we can't find what we want..
        clearNativeLocation();
        log.info("Unable to locate native components");
        return false;
    }

}
